package com.dhcc.DRGsHosp.facade.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import javax.inject.Named;

import org.openkoala.koala.commons.InvokeResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;

import com.dhcc.DRGsHosp.application.AnnualSTDApplication;
import com.dhcc.DRGsHosp.application.DrgsIndexCalApplication;
import com.dhcc.DRGsHosp.application.SizerConditionApplication;
import com.dhcc.DRGsHosp.application.SpecialMonitorApplication;
import com.dhcc.DRGsHosp.core.domain.AnnualSTD;
import com.dhcc.DRGsHosp.core.domain.SizerCondition;
import com.dhcc.DRGsHosp.facade.DrgsIndexCalFacade;
import com.dhcc.DRGsHosp.facade.SpecialMonitorFacade;
import com.dhcc.DRGsHosp.facade.dto.IndexCalDTO;
import com.dhcc.DRGsHosp.facade.dto.SizerConditionDTO;
import com.dhcc.DRGsHosp.facade.impl.assembler.IndexCalAssembler;
import com.dhcc.DRGsHosp.facade.impl.assembler.SizerConditionAssembler;
import com.dhcc.DRGsHosp.infra.util.DrgsIndex;
import com.dhcc.DRGsHosp.infra.util.MapComparatorImpl;
import com.dhcc.DRGsHosp.infra.util.MonitorResultUtil;
import com.dhcc.DRGsHosp.infra.util.StringUtils;
import com.dhcc.DRGsHosp.weightInterval.WeightInterval;

/**
 * @title		:SpecialMonitorFacadeImpl.java
 * @description	:专科建设指标监测
 * @author		:lileizheng
 * @date		:2016年3月4日
 * @version     :1.0
 * @copyright   :DHCC 2013-2014 
 */
@Named("drgsHospFacadeImpl43")
public class SpecialMonitorFacadeImpl implements SpecialMonitorFacade {
	
	@Autowired
	private SpecialMonitorApplication specialMonitorApplication;
	@Autowired
	private DrgsIndexCalApplication  drgsIndexCalApplication;
	@Autowired
	private DrgsIndexCalFacade drgsIndexCalFacade;
	@Autowired
	private SizerConditionApplication sizerConditionApplication;
	@Autowired
	private AnnualSTDApplication annualSTDApplication;
	
	private static final Logger LOGGER = LoggerFactory.getLogger(DrgsIndexCalFacadeImpl.class);
	
	List<Map<String, Object>> weightInterlist = new LinkedList<>();//定义一个全局变量，存放已经算好的权重区间,方便以后使用

	@Override
	public InvokeResult getSpecTotalScore(IndexCalDTO dto){
		dto.setDateFrom(DrgsIndex.formateDateFrom(dto.getDateFrom()));
		dto.setDateTo(DrgsIndex.formateDateTo(dto.getDateTo()));
		dto.setVerRegion(drgsIndexCalFacade.getGroupScheme());
		dto.setStdId(drgsIndexCalFacade.getStdID(dto.getDateFrom(), dto.getDateTo()));
		List<Map<String, Object>> resultList = monitorSpecTotalScore(dto);
		Collections.sort(resultList, new MapComparatorImpl("ccode", "asc"));
		
		String dateFromLY = MonitorResultUtil.getLastYearMrDate(dto.getDateFrom());
		String dateToLY = MonitorResultUtil.getLastYearMrDate(dto.getDateTo());
		dto.setDateFrom(dateFromLY);
		dto.setDateTo(dateToLY);
		List<Map<String, Object>> resultListcc = monitorSpecTotalScore(dto);
		Collections.sort(resultListcc, new MapComparatorImpl("ccode", "asc"));
		resultList = mapList(resultList, resultListcc, "cc");
		return InvokeResult.success(resultList);
	}
	
	public List<Map<String, Object>> monitorSpecTotalScore(IndexCalDTO dto) {
		//计算产能得分
		dto.setQuotaCode("spCapScore");
		List<Map<String, Object>> listCap = monitor(dto);
		
		//计算效率得分
		dto.setQuotaCode("spEffScore");
		List<Map<String, Object>> listEff = monitor(dto);
		//计算安全得分
		dto.setQuotaCode("spQuaScore");
		List<Map<String, Object>> listQua = monitor(dto);
		
		listCap = mapList(listCap, listEff, "");
		listCap = mapList(listCap, listQua, "");
		//计算安全得分基准值
		dto.setQuotaCode("spQuaScores");
		List<Map<String, Object>> listQuas = monitor(dto);
		
		listCap = mapList(listCap, listQuas, "");
		
		double spCapScores = 1*0.204+0.75*0.181;
		double spEffScores = 0.192+0.128;
		int s1=0, s2=0, s3=0, s4=0;
		List<Map<String, Object>> resultList = new LinkedList<>();
		for(Map<String, Object> m: listCap){
			double spCapScore = m.get("spCapScore")!=null?Double.parseDouble(m.get("spCapScore").toString()):0;
			double spEffScore = m.get("spEffScore")!=null?Double.parseDouble(m.get("spEffScore").toString()):0;
			double spQuaScore = m.get("spQuaScore")!=null?Double.parseDouble(m.get("spQuaScore").toString()):0;
			double spQuaScores = m.get("spQuaScores")!=null?Double.parseDouble(m.get("spQuaScores").toString()):0;
			double spTotalScore = spCapScore + spEffScore + spQuaScore;
			Map<String, Object> map = new HashMap<>();
			map.put("ccode", m.get("ccode"));
			map.put("ddesc", m.get("ddesc"));
			map.put("spTotalScore", String.format("%.3f", spTotalScore));
			if(spCapScore<spCapScores){
				map.put("spType", "1");
				s1++;
			}else if(spEffScore<spEffScores){
				map.put("spType", "2");
				s2++;
			}else if(spQuaScore<spQuaScores){
				map.put("spType", "3");
				s3++;
			}else{
				map.put("spType", "4");
				s4++;
			}
			resultList.add(map);
		}
		Collections.sort(resultList, new MapComparatorImpl("spTotalScore", "desc"));
		for(int i=1; i<resultList.size()+1; i++){
			Map<String, Object> map = resultList.get(i-1);
			map.put("spIndex", i);
			if("1".equals(map.get("spType"))){
				map.put("spTypeCount", s1);
			}else if("2".equals(map.get("spType"))){
				map.put("spTypeCount", s2);
			}else if("3".equals(map.get("spType"))){
				map.put("spTypeCount", s3);
			}else{
				map.put("spTypeCount", s4);
			}
		}
		return resultList;
	}
	@Override
	public InvokeResult getCMITotalWeightRatio(IndexCalDTO dto){
		dto.setDateFrom(DrgsIndex.formateDateFrom(dto.getDateFrom()));
		dto.setDateTo(DrgsIndex.formateDateTo(dto.getDateTo()));
		dto.setStdId(drgsIndexCalFacade.getStdID(dto.getDateFrom(), dto.getDateTo()));
		dto.setVerRegion(drgsIndexCalFacade.getGroupScheme());
		String[] quotaCodea = dto.getQuotaCode().split(",") ;
		List<Map<String, Object>> resultList = new ArrayList<>() ;
		//CMI
		dto.setQuotaCode(quotaCodea[0]);
		resultList = monitor(dto);
		//总权重全院占比
		dto.setQuotaCode(quotaCodea[1]);
		List<Map<String, Object>> listTemp = monitor(dto);
		mapList(resultList, listTemp, "");
		return InvokeResult.success(resultList);
	}
	
	
	public List<Map<String, Object>> monitor(IndexCalDTO dto){
		dto.setVerCode(drgsIndexCalFacade.getVerCode(dto.getDateFrom(), dto.getDateTo()));
		String unit = drgsIndexCalApplication.getUnitByQuotaCode(dto.getQuotaCode());
		List<Object[]> resultList = specialMonitorApplication.monitor(IndexCalAssembler.toEntity(dto));
		List<Map<String, Object>> list = new LinkedList<>();
		for(Object[] objs: resultList){
			Map<String, Object> map = new HashMap<>();
			map.put("ccode", objs[0]);
			map.put("ddesc", objs[1]);
			String value = null;
			if(objs[2]!=null){
				value = String.format("%."+unit+"f", Double.parseDouble(objs[2].toString()));
			}
			map.put(dto.getQuotaCode(), value);
			list.add(map);
		}
		if(resultList.size()<=0){
			Map<String, Object> map = new HashMap<>();
			list.add(map);
		}
		return list;
	}
	
	public static List<Map<String, Object>> mapList(List<Map<String, Object>> list1, List<Map<String, Object>> list2, String ss){
    	int i=0;
    	int j=0;
    	int iMax=list1.size();
    	int jMax=list2.size();
    		for(i=0; i<iMax; i++){
        		int k=j;
        		Map<String, Object> map1 = list1.get(i);
        		String ccode1 = map1.get("ccode")!=null?map1.get("ccode").toString():"";
        		while(true){
        			if(k==jMax) {
        				break;
        			}
        			Map<String, Object> map2 = list2.get(k);
            		String ccode2 = map2.get("ccode")!=null?map2.get("ccode").toString():"";
        			if(ccode2.equals(ccode1)){
        				 for(String dataKey : map2.keySet())   {    
        					 map1.put(dataKey+ss, map2.get(dataKey));
        				 } 
        				 j++;
        				 break;
        			}
        			k++;
        		}
        	}
    	return list1;
    }
	
	//获取7大指标值
	private List<Map<String, Object>> get7Quotas(IndexCalDTO indexDto){
		String[] quotas = {"spTotalWeight","spCMI","spDRGsCount","spTimeEff","spFeeEff",
				"spRisk1DeadRatio","spRisk2DeadRatio","spCureRatio"};
		indexDto.setQuotaCode("spTotalCaseCnt");
		List<Map<String, Object>> listTotalCaseCnt = monitor(indexDto);
		
		ExecutorService indexPool = Executors.newFixedThreadPool(quotas.length);
		List<Future<List<Map<String,Object>>>> listf = new ArrayList<>();
		for(int i=0;i<quotas.length;i++){
			IndexCalDTO dto = (IndexCalDTO) DrgsIndex.copyPropertiesObj(indexDto);
			dto.setQuotaCode(quotas[i]);
			QuotaCallable c = new QuotaCallable(dto);
			listf.add(indexPool.submit(c));
		}
		indexPool.shutdown();
		try{
			for(Future<List<Map<String,Object>>> list:listf){
				listTotalCaseCnt = mapList(listTotalCaseCnt, list.get(),"");
			}
		}catch(Exception e){
			LOGGER.error(e.getMessage());
			e.printStackTrace();
		}
		
		return listTotalCaseCnt;
	}
	
	private class QuotaCallable implements Callable<List<Map<String,Object>>> {
		private IndexCalDTO indexDto;
		private QuotaCallable (IndexCalDTO indexDto){
			this.indexDto = indexDto;
		}
		@Override
		public List<Map<String,Object>> call(){
			List<Map<String,Object>> listQuota = monitor(indexDto);
			return listQuota;
		}
	}
	
	//获取7大指标基准值
	private List<Map<String, Object>> get7QuotasJiZZ(IndexCalDTO dto){
//		dto.setDateFrom(DrgsIndex.formateDateFrom(dto.getDateFrom()));
//		dto.setDateTo(DrgsIndex.formateDateTo(dto.getDateTo()));
//		dto.setVerRegion(drgsIndexCalFacade.getGroupScheme());
//		dto.setStdId(drgsIndexCalFacade.getStdID(dto.getDateFrom(), dto.getDateTo()));
		dto.setQuotaCode("spCMIs");
		List<Map<String, Object>> listCMI = monitor(dto);
		dto.setQuotaCode("spDRGsCounts");
		List<Map<String, Object>> listDRGsCount = monitor(dto);
		dto.setQuotaCode("spTimeEffs");
		List<Map<String, Object>> listTimeEff = monitor(dto);
		dto.setQuotaCode("spFeeEffs");
		List<Map<String, Object>> listFeeEff = monitor(dto);
		dto.setQuotaCode("spRisk1DeadRatios");
		List<Map<String, Object>> listRisk1DeadRatio = monitor(dto);
		dto.setQuotaCode("spRisk2DeadRatios");
		List<Map<String, Object>> listRisk2DeadRatio = monitor(dto);
		dto.setQuotaCode("spCureRatios");
		List<Map<String, Object>> listCureRatio = monitor(dto);
		listCMI = mapList(listCMI, listCMI, "");
		listCMI = mapList(listCMI, listDRGsCount, "");
		listCMI = mapList(listCMI, listTimeEff, "");
		listCMI = mapList(listCMI, listFeeEff, "");
		listCMI = mapList(listCMI, listRisk1DeadRatio, "");
		listCMI = mapList(listCMI, listRisk2DeadRatio, "");
		listCMI = mapList(listCMI, listCureRatio, "");
		return listCMI;
	}

	@Override
	public InvokeResult getAnalysisQuotas(IndexCalDTO dto) {
		dto.setDateFrom(DrgsIndex.formateDateFrom(dto.getDateFrom()));
		dto.setDateTo(DrgsIndex.formateDateTo(dto.getDateTo()));
		dto.setStdId(drgsIndexCalFacade.getStdID(dto.getDateFrom(), dto.getDateTo()));
		dto.setVerRegion(drgsIndexCalFacade.getGroupScheme());
		return InvokeResult.success(get7Quotas(dto));
	}

	@Override
	public InvokeResult getAnalysisQuotasAndJizhunzhi(IndexCalDTO dto) {
		dto.setDateFrom(DrgsIndex.formateDateFrom(dto.getDateFrom()));
		dto.setDateTo(DrgsIndex.formateDateTo(dto.getDateTo()));
		dto.setVerRegion(drgsIndexCalFacade.getGroupScheme());
		dto.setStdId(drgsIndexCalFacade.getStdID(dto.getDateFrom(), dto.getDateTo()));
		//获取7大指标值
		List<Map<String, Object>> listCMI = get7Quotas(dto);
		
		//获取基准值
		List<Map<String, Object>> listCMIs = get7QuotasJiZZ(dto);
		
		listCMI = mapList(listCMI, listCMIs, "");
		return InvokeResult.success(listCMI);
	}

	@Override
	public InvokeResult getGukeData(IndexCalDTO dto) {
		dto.setDateFrom(DrgsIndex.formateDateFrom(dto.getDateFrom()));
		dto.setDateTo(DrgsIndex.formateDateTo(dto.getDateTo()));
		dto.setStdId(drgsIndexCalFacade.getStdID(dto.getDateFrom(), dto.getDateTo()));
		dto.setVerRegion(drgsIndexCalFacade.getGroupScheme());
		List<Map<String, Object>> listCMI = get7Quotas(dto);
		List<Map<String, Object>> listCMIs = get7QuotasJiZZ(dto);
		listCMI = mapList(listCMI, listCMIs, "");
		
		//计算产能得分
		dto.setQuotaCode("spCapScore");
		List<Map<String, Object>> listCap = monitor(dto);
		double spCapScore = 0;
		for(Map<String, Object> m: listCap){
			spCapScore = m.get("spCapScore")!=null?Double.parseDouble(m.get("spCapScore").toString()):0;
		}
		//计算效率得分
		dto.setQuotaCode("spEffScore");
		List<Map<String, Object>> listEff = monitor(dto);
		double spEffScore = 0;
		for(Map<String, Object> m: listEff){
			spEffScore = m.get("spEffScore")!=null?Double.parseDouble(m.get("spEffScore").toString()):0;
		}
		//计算安全得分
		dto.setQuotaCode("spQuaScore");
		List<Map<String, Object>> listQua = monitor(dto);
		
		double spQuaScore = 0;
		for(Map<String, Object> m: listQua){
			spQuaScore = m.get("spQuaScore")!=null?Double.parseDouble(m.get("spQuaScore").toString()):0;
		}
		double spTotalScore = spCapScore + spEffScore + spQuaScore;
		//产能效率安全得分的基准值
		double spCapScores = 1*0.204+0.75*0.181;
		double spEffScores = 0.192+0.128;
		double spQuaScores = 0;
		//计算安全得分基准值
		dto.setQuotaCode("spQuaScores");
		List<Map<String, Object>> listQuas = monitor(dto);
		for(Map<String, Object> m: listQuas){
			spQuaScores = m.get("spQuaScores")!=null?Double.parseDouble(m.get("spQuaScores").toString()):0;
		}
		//同期值
		String dateFromLY = MonitorResultUtil.getLastYearMrDate(dto.getDateFrom());
		String dateToLY = MonitorResultUtil.getLastYearMrDate(dto.getDateTo());
		dto.setDateFrom(dateFromLY);
		dto.setDateTo(dateToLY);
		List<Map<String, Object>> listCMI2 = get7Quotas(dto);
		listCMI = mapList(listCMI, listCMI2, "cc");
		
		Map<String, Object> result = new HashMap<>();
		if(listCMI.size()>0){
			result = listCMI.get(0);
		}
		
		result.put("spCapScore", spCapScore);
		result.put("spEffScore", spEffScore);
		result.put("spQuaScore", spQuaScore);
		result.put("spTotalScore", spTotalScore);
		
		result.put("spCapScores", spCapScores);
		result.put("spEffScores", spEffScores);
		result.put("spQuaScores", spQuaScores);
		
		return InvokeResult.success(result);
	}
	
	@Override
	public InvokeResult getSpecialData(IndexCalDTO dto) {
		dto.setDateFrom(DrgsIndex.formateDateFrom(dto.getDateFrom()));
		dto.setDateTo(DrgsIndex.formateDateTo(dto.getDateTo()));
		dto.setStdId(drgsIndexCalFacade.getStdID(dto.getDateFrom(), dto.getDateTo()));
		dto.setVerRegion(drgsIndexCalFacade.getGroupScheme());
		//获取本期指标值
		dto.setQuotaCode("spDRGsCounts");
		List<Map<String, Object>> listDRGsCounts = monitor(dto);
		dto.setQuotaCode("spDRGsCount");
		List<Map<String, Object>> listDRGsCount = monitor(dto);
		dto.setQuotaCode("spDRGsCountsTheoretical");
		List<Map<String, Object>> listDRGsCountTheoretical = monitor(dto);
		dto.setQuotaCode("spTotalCaseCnt");
		List<Map<String, Object>> listTotalCaseCnt = monitor(dto);
		dto.setQuotaCode("spTotalWeight");
		List<Map<String, Object>> listTotalWeight = monitor(dto);
		//总权重全院占比
		dto.setQuotaCode("spTotalWeightRatio");
		List<Map<String, Object>> listTotalWeightRatio = monitor(dto);
		//出院病例数全院占比
		dto.setQuotaCode("spTotalCaseCntRatio");
		List<Map<String, Object>> listTotalCaseCntRatio = monitor(dto);
		listDRGsCounts = mapList(listDRGsCounts, listDRGsCount, "");
		listDRGsCounts = mapList(listDRGsCounts, listDRGsCountTheoretical, "");
		listDRGsCounts = mapList(listDRGsCounts, listTotalCaseCnt, "");
		listDRGsCounts = mapList(listDRGsCounts, listTotalWeight, "");
		listDRGsCounts = mapList(listDRGsCounts, listTotalWeightRatio, "");
		listDRGsCounts = mapList(listDRGsCounts, listTotalCaseCntRatio, "");
		for(Map<String, Object> map: listDRGsCounts){
			Double drgsCount = map.get("spDRGsCount")!=null?Double.parseDouble(map.get("spDRGsCount").toString()):0;
			Double drgsCounts = map.get("spDRGsCountsTheoretical")!=null?Double.parseDouble(map.get("spDRGsCountsTheoretical").toString()):0;
			Double drgsCountRatio = drgsCounts!=0?drgsCount/drgsCounts*100:0;
			map.put("spDRGsCountRatio", String.format("%.2f", drgsCountRatio));
		}
		
		//获取同期值
		String dateFromLY = MonitorResultUtil.getLastYearMrDate(dto.getDateFrom());
		String dateToLY = MonitorResultUtil.getLastYearMrDate(dto.getDateTo());
		dto.setDateFrom(dateFromLY);
		dto.setDateTo(dateToLY);
		dto.setQuotaCode("spDRGsCounts");
		List<Map<String, Object>> listDRGsCountscc = monitor(dto);
		dto.setQuotaCode("spDRGsCount");
		List<Map<String, Object>> listDRGsCountcc = monitor(dto);
		dto.setQuotaCode("spDRGsCountsTheoretical");
		List<Map<String, Object>> listDRGsCountTheoreticalcc = monitor(dto);
		dto.setQuotaCode("spTotalCaseCnt");
		List<Map<String, Object>> listTotalCaseCntcc = monitor(dto);
		dto.setQuotaCode("spTotalWeight");
		List<Map<String, Object>> listTotalWeightcc = monitor(dto);
		//总权重全院占比
		dto.setQuotaCode("spTotalWeightRatio");
		List<Map<String, Object>> listTotalWeightRatiocc = monitor(dto);
		//出院病例数全院占比
		dto.setQuotaCode("spTotalCaseCntRatio");
		List<Map<String, Object>> listTotalCaseCntRatiocc = monitor(dto);
		listDRGsCountscc = mapList(listDRGsCountscc, listDRGsCountcc, "");
		listDRGsCountscc = mapList(listDRGsCountscc, listDRGsCountTheoreticalcc, "");
		listDRGsCountscc = mapList(listDRGsCountscc, listTotalCaseCntcc, "");
		listDRGsCountscc = mapList(listDRGsCountscc, listTotalWeightcc, "");
		listDRGsCountscc = mapList(listDRGsCountscc, listTotalWeightRatiocc, "");
		listDRGsCountscc = mapList(listDRGsCountscc, listTotalCaseCntRatiocc, "");
		for(Map<String, Object> map: listDRGsCountscc){
			Double drgsCountcc = map.get("spDRGsCount")!=null?Double.parseDouble(map.get("spDRGsCount").toString()):0;
			Double drgsCountsTheoreticalcc = map.get("spDRGsCountsTheoretical")!=null?Double.parseDouble(map.get("spDRGsCountsTheoretical").toString()):0;
			Double drgsCountRatiocc = drgsCountsTheoreticalcc!=0?drgsCountcc/drgsCountsTheoreticalcc*100:0;
			map.put("spDRGsCountRatio", String.format("%.2f", drgsCountRatiocc));
		}
		listDRGsCounts = mapList(listDRGsCounts, listDRGsCountscc, "cc");
		return InvokeResult.success(listDRGsCounts);
	}
	
	@Override
	@Cacheable(value = "drgscom3.1.1", key = "'weightInter' + #dto.specCode + "
			+ "#dto.dateFrom + #dto.dateTo ")
	public InvokeResult getWeightInter(IndexCalDTO dto){
		String dateFrom = DrgsIndex.formateDateFrom(dto.getDateFrom()) ;
		String dateTo = DrgsIndex.formateDateTo(dto.getDateTo()) ;
		dto.setDateFrom(dateFrom);
		dto.setDateTo(dateTo);
		dto.setStdId(drgsIndexCalFacade.getStdID(dto.getDateFrom(), dto.getDateTo()));
		dto.setVerRegion(drgsIndexCalFacade.getGroupScheme());
		dto.setVerCode(drgsIndexCalFacade.getVerCode(dateFrom, dateTo));
		List<Map<String, Object>> resultList = new LinkedList<>();
		List<String> weightListString = specialMonitorApplication.getWeights(IndexCalAssembler.toEntity(dto));
//		List<Double> weightList = weightListString.stream().map(s -> Double.parseDouble(s.trim())).collect(Collectors.toList()); 
		List<Double> weightList = new ArrayList<>() ;
		for(String str : weightListString) {
			if(StringUtils.hasLength(str)){
				weightList.add(Double.parseDouble(str)) ;
			}
		}
		Double weightMax = Collections.max(weightList) ;
		if(weightList.size() == 0) {
			return InvokeResult.failure("病组权重为空");
		}
		//统计DRGs组数
		int drgs = 0;
		dto.setQuotaCode("spDRGsCount");
		List<Map<String, Object>> listDRGsCount = monitor(dto);
		if(listDRGsCount.size()>0) {
			Map<String, Object> map = listDRGsCount.get(0);
			drgs = map.get("spDRGsCount")!=null?Integer.parseInt(map.get("spDRGsCount").toString()):0;
		}
		
		double[] dous = WeightInterval.calcWeightInterval(weightList, drgs);
		if(dous!=null && dous.length>0){
			Double weight1 = 0d;
			Double weight2 = dous[0];
			Map<String, Object> map = specialMonitorApplication.getQuotasByWeightInterval(IndexCalAssembler.toEntity(dto), weight1, weight2);
			map.put("ddesc", weight1+"-"+weight2);
//			map.put("weight1", weight1);
//			map.put("weight2", weight2);
			resultList.add(map);
			if(dous.length>1){
				weight1 = dous[0];
				weight2 = dous[1];
				map = specialMonitorApplication.getQuotasByWeightInterval(IndexCalAssembler.toEntity(dto), weight1, weight2);
				map.put("ddesc", weight1+"-"+weight2);
				resultList.add(map);
				if(dous.length>2){
					weight1 = dous[1];
					weight2 = dous[2];
					map = specialMonitorApplication.getQuotasByWeightInterval(IndexCalAssembler.toEntity(dto), weight1, weight2);
					map.put("ddesc", weight1+"-"+weight2);
					resultList.add(map);
					weight1 = dous[2];
					weight2 = weightMax;
//					weight2 = null;
					map = specialMonitorApplication.getQuotasByWeightInterval(IndexCalAssembler.toEntity(dto), weight1, weight2);
					map.put("ddesc", weight1+"-"+weightMax);
					resultList.add(map);
				}else{
					weight1 = dous[1];
					weight2 = weightMax;
//					weight2 = null;
					map = specialMonitorApplication.getQuotasByWeightInterval(IndexCalAssembler.toEntity(dto), weight1, weight2);
					map.put("ddesc", weight1+"-"+weightMax);
					resultList.add(map);
				}
			}else{
				weight1 = dous[0];
				weight2 = null;
				map = specialMonitorApplication.getQuotasByWeightInterval(IndexCalAssembler.toEntity(dto), weight1, weight2);
				resultList.add(map);
			}
		}
		
		dto.setQuotaCode("spTotalCaseCnt");
		List<Map<String, Object>> totalCaseCntList = monitor(dto);
		double totalCaseCnt = 0;
		if(totalCaseCntList.size()>0){
			totalCaseCnt = Double.parseDouble(totalCaseCntList.get(0).get("spTotalCaseCnt").toString());
		}
		dto.setQuotaCode("spTotalWeight");
		List<Map<String, Object>> totalWeightList = monitor(dto);
		double totalWeight = 0;
		if(totalCaseCntList.size()>0){
			totalWeight = Double.parseDouble(totalWeightList.get(0).get("spTotalWeight").toString());
		}
		//查找优势权重区间
		for(Map<String, Object> map: resultList) {
			double totalCaseCntw = map.get("totalCaseCnt")!=null?Double.parseDouble(map.get("totalCaseCnt").toString()):0;
			double totalWeightw = map.get("totalWeight")!=null?Double.parseDouble(map.get("totalWeight").toString()):0;
			double totalCaseCntRatio = totalCaseCnt!=0?(totalCaseCntw/totalCaseCnt*100):0;
			double totalWeigtRatio = totalWeight!=0?(totalWeightw/totalWeight*100):0;
			double drgsCount = map.get("drgsCount")!=null?Double.parseDouble(map.get("drgsCount").toString()):0;
			double drgsCounts = map.get("drgsCounts")!=null?Double.parseDouble(map.get("drgsCounts").toString()):0;
			double drgsCountRatio = drgsCounts!=0?(drgsCount/drgsCounts*100):0;
			map.put("totalCaseCntRatio", String.format("%.2f", totalCaseCntRatio));
			map.put("totalWeightRatio", String.format("%.2f", totalWeigtRatio));
			map.put("drgsCountRatio", String.format("%.2f", drgsCountRatio));
			// 100/(区间个数)
			if(totalCaseCntRatio>(100/resultList.size()) && totalWeigtRatio>(100/resultList.size())){
				map.put("hasAdvantage", true);
			}else{
				double timeEff =  map.get("timeEff")!=null?Double.parseDouble(map.get("timeEff").toString()):0;
				double feeEff = map.get("feeEff")!=null?Double.parseDouble(map.get("feeEff").toString()):0;
				double risk0DeadEff = map.get("risk0DeadEff")!=null?Double.parseDouble(map.get("risk0DeadEff").toString()):0;
				if(timeEff<1 && feeEff<1 && risk0DeadEff<1){
					map.put("hasAdvantage", true);
				}
			}
		}
		weightInterlist = resultList;
		Map<String,Object> resultMap = new HashMap<>() ;
		Collections.max(weightList) ;
		resultMap.put("weightMin",Collections.min(weightList)) ;
		resultMap.put("weightMax", weightMax) ;
		resultMap.put("weightRange", resultList) ;
		return InvokeResult.success(resultMap);
	}
	
	@Override
	public InvokeResult getWeightInterDeps(IndexCalDTO dto, String weightInter){
		String dateFrom = DrgsIndex.formateDateFrom(dto.getDateFrom()) ;
		String dateTo = DrgsIndex.formateDateTo(dto.getDateTo()) ;
		dto.setDateFrom(dateFrom);
		dto.setDateTo(dateTo);
		dto.setStdId(drgsIndexCalFacade.getStdID(dto.getDateFrom(), dto.getDateTo()));
		dto.setVerRegion(drgsIndexCalFacade.getGroupScheme());
		dto.setVerCode(drgsIndexCalFacade.getVerCode(dateFrom, dateTo));
		String[] weights = weightInter.split("-");
		String weight1 = weights[0];
		String weight2 = null;
		if(weights.length>1) {
			weight2 = weights[1];
		}
		List<Map<String, Object>> resultList = specialMonitorApplication.getQuotasDepByWeightInter(IndexCalAssembler.toEntity(dto), weight1, weight2);
		//判断优势科室
		if(resultList.size()==1){
			Map<String, Object> map = resultList.get(0);
			map.put("hasAdvantage", true);
		}else{
			boolean isEnd = false;
			for(Map<String, Object> map: resultList){
				Double totalWeightRatio = map.get("totalWeightRatio")!=null?Double.parseDouble(map.get("totalWeightRatio").toString()):0;
				Double totalCaseCntRatio = map.get("totalCaseCntRatio")!=null?Double.parseDouble(map.get("totalCaseCntRatio").toString()):0;
				// 100/(科室个数)
				if(totalWeightRatio>(100/resultList.size()) && totalCaseCntRatio>(100/resultList.size())){
					map.put("hasAdvantage", true);
					isEnd = true;
					break;
				}
			}
			if(!isEnd){
				List<Map<String, Object>> timefeedeadEffList = specialMonitorApplication.getDepsInnerTimeFeeDeadEff(IndexCalAssembler.toEntity(dto), null, null);
				resultList = mapList(resultList, timefeedeadEffList, "");
				for(Map<String, Object> map: resultList){
					Double timeEff = map.get("timeEff")!=null?Double.parseDouble(map.get("timeEff").toString()):0;
					Double feeEff = map.get("feeEff")!=null?Double.parseDouble(map.get("feeEff").toString()):0;
					Double deadEff = map.get("deadEff")!=null?Double.parseDouble(map.get("deadEff").toString()):0;
					Double timeEffIn = map.get("timeEffIn")!=null?Double.parseDouble(map.get("timeEffIn").toString()):0;
					Double feeEffIn = map.get("feeEffIn")!=null?Double.parseDouble(map.get("feeEffIn").toString()):0;
					Double deadEffIn = map.get("deadEffIn")!=null?Double.parseDouble(map.get("deadEffIn").toString()):0;
					if(timeEff<1 && feeEff<1 && deadEff<1 && timeEffIn<1 && feeEffIn<1 && deadEffIn<1){
						map.put("hasAdvantage", true);
						isEnd = true;
					}
					double totalEff = (timeEff!=0?1/timeEff:0)*0.4 + (feeEff!=0?1/feeEff:0)*0.4 + (deadEff!=0?1/deadEff:0)*0.2;
					double totalEffIn = (timeEffIn!=0?1/timeEffIn:0)*0.4 + (feeEffIn!=0?1/feeEffIn:0)*0.4 + (deadEffIn!=0?1/deadEffIn:0)*0.2;
					map.put("totalEffs", totalEff+totalEffIn);
				}
			}
			if(!isEnd){
				Collections.sort(resultList, new MapComparatorImpl("totalEffs", "desc"));
				Map<String, Object> map = resultList.get(0);
				map.put("hasAdvantage", true);
			}
		}
		Collections.sort(resultList, new MapComparatorImpl("totalCaseCnt", "desc"));
		return InvokeResult.success(resultList);
	}
	
	@Override
	public InvokeResult getDepsQuotas(IndexCalDTO dto){
		String dateFrom = DrgsIndex.formateDateFrom(dto.getDateFrom());
		String dateTo = DrgsIndex.formateDateTo(dto.getDateTo());
		dto.setDateFrom(dateFrom);
		dto.setDateTo(dateTo);
		dto.setStdId(drgsIndexCalFacade.getStdID(dto.getDateFrom(), dto.getDateTo()));
		dto.setVerRegion(drgsIndexCalFacade.getGroupScheme());
		dto.setVerCode(drgsIndexCalFacade.getVerCode(dateFrom, dateTo));
		List<Map<String, Object>> resultList = specialMonitorApplication.getQuotasDepByWeightInter(IndexCalAssembler.toEntity(dto), null, null);
		//判断优势科室
		if(resultList.size()==1){
			Map<String, Object> map = resultList.get(0);
			map.put("hasAdvantage", true);
		}else{
			boolean isEnd = false;
			for(Map<String, Object> map: resultList){
				Double totalWeightRatio = map.get("totalWeightRatio")!=null?Double.parseDouble(map.get("totalWeightRatio").toString()):0;
				Double totalCaseCntRatio = map.get("totalCaseCntRatio")!=null?Double.parseDouble(map.get("totalCaseCntRatio").toString()):0;
				if(totalWeightRatio>70 && totalCaseCntRatio>70){
					map.put("hasAdvantage", true);
					isEnd = true;
					break;
				}
			}
			if(!isEnd){
				List<Map<String, Object>> timefeedeadEffList = specialMonitorApplication.getDepsInnerTimeFeeDeadEff(IndexCalAssembler.toEntity(dto), null, null);
				resultList = mapList(resultList, timefeedeadEffList, "");
				for(Map<String, Object> map: resultList){
					Double timeEff = map.get("timeEff")!=null?Double.parseDouble(map.get("timeEff").toString()):0;
					Double feeEff = map.get("feeEff")!=null?Double.parseDouble(map.get("feeEff").toString()):0;
					Double deadEff = map.get("deadEff")!=null?Double.parseDouble(map.get("deadEff").toString()):0;
					Double timeEffIn = map.get("timeEffIn")!=null?Double.parseDouble(map.get("timeEffIn").toString()):0;
					Double feeEffIn = map.get("feeEffIn")!=null?Double.parseDouble(map.get("feeEffIn").toString()):0;
					Double deadEffIn = map.get("deadEffIn")!=null?Double.parseDouble(map.get("deadEffIn").toString()):0;
					if(timeEff<1 && feeEff<1 && deadEff<1 && timeEffIn<1 && feeEffIn<1 && deadEffIn<1){
						map.put("hasAdvantage", true);
						isEnd = true;
					}
					double totalEff = (timeEff!=0?1/timeEff:0)*0.4 + (feeEff!=0?1/feeEff:0)*0.4 + (deadEff!=0?1/deadEff:0)*0.2;
					double totalEffIn = (timeEffIn!=0?1/timeEffIn:0)*0.4 + (feeEffIn!=0?1/feeEffIn:0)*0.4 + (deadEffIn!=0?1/deadEffIn:0)*0.2;
					map.put("totalEffs", totalEff+totalEffIn);
				}
			}
			if(!isEnd){
				Collections.sort(resultList, new MapComparatorImpl("totalEffs", "desc"));
				Map<String, Object> map = resultList.get(0);
				map.put("hasAdvantage", true);
			}
		}
		Collections.sort(resultList, new MapComparatorImpl("totalCaseCnt", "desc"));
		return InvokeResult.success(resultList);
	}

	@Override
	public InvokeResult getDRGsQuotas(IndexCalDTO dto, String weightInter) {
		dto.setDateFrom(DrgsIndex.formateDateFrom(dto.getDateFrom()));
		dto.setDateTo(DrgsIndex.formateDateTo(dto.getDateTo()));
		dto.setStdId(drgsIndexCalFacade.getStdID(dto.getDateFrom(), dto.getDateTo()));
		dto.setVerRegion(drgsIndexCalFacade.getGroupScheme());
		String weight1 = null;
		String weight2 = null;
		if(StringUtils.hasLength(weightInter)){
			String[] weights = weightInter.split("-");
			weight1 = weights[0];
			if(weights.length>1) {
				weight2 = weights[1];
			}
		}
		List<Map<String, Object>> resultList = specialMonitorApplication.getDRGsByDepsOrWeight(IndexCalAssembler.toEntity(dto), weight1, weight2);
		//获取保持优势，弥补不足，引导发展病组
		List<Map<String, Object>> list1 = new LinkedList<>();
		List<Map<String, Object>> list2 = new LinkedList<>();
		Collections.sort(resultList, new MapComparatorImpl("totalCaseCnt", "desc"));
		double totalCaseCntss=0;
		for(Map<String, Object> map: resultList){
			double totalCaseCnt = map.get("totalCaseCnt")!=null?Double.parseDouble(map.get("totalCaseCnt").toString()):0;
			totalCaseCntss += totalCaseCnt;
			double totalCaseCnts = map.get("totalCaseCnts")!=null?Double.parseDouble(map.get("totalCaseCnts").toString()):0;
			if(totalCaseCnts !=0 && totalCaseCntss/totalCaseCnts>=0.8){
				break;
			}
			list1.add(map);
		}
		Collections.sort(resultList, new MapComparatorImpl("totalWeight", "desc"));
		double totalWeightss=0;
		for(Map<String, Object> map: resultList){
			double totalWeight = map.get("totalWeight")!=null?Double.parseDouble(map.get("totalWeight").toString()):0;
			totalWeightss += totalWeight;
			double totalWeights = map.get("totalWeights")!=null?Double.parseDouble(map.get("totalWeights").toString()):0;
			if(totalWeights !=0 && totalWeightss/totalWeights>=0.8){
				break;
			}
			list2.add(map);
		}
		//无重复并集
		list2.removeAll(list1);
	    list1.addAll(list2);
	    for(Map<String, Object> map: list1){
	    	double timeEff = map.get("timeEff")!=null?Double.parseDouble(map.get("timeEff").toString()):0;
	    	double feeEff = map.get("feeEff")!=null?Double.parseDouble(map.get("feeEff").toString()):0;
	    	double deadEff = map.get("deadEff")!=null?Double.parseDouble(map.get("deadEff").toString()):0;
	    	if((timeEff<=1 && feeEff<=1) || (timeEff<=1 && deadEff<=1) || (feeEff<=1 && deadEff<=1)){
	    		map.put("hasAdvantage", "1");
	    	}else{
	    		map.put("hasAdvantage", "2");
	    	}
	    }
	    //获取剩余DRGs
	    resultList.removeAll(list1);
	    for(Map<String, Object> map: resultList){
	    	double timeEff = map.get("timeEff")!=null?Double.parseDouble(map.get("timeEff").toString()):0;
	    	double feeEff = map.get("feeEff")!=null?Double.parseDouble(map.get("feeEff").toString()):0;
	    	double deadEff = map.get("deadEff")!=null?Double.parseDouble(map.get("deadEff").toString()):0;
	    	if(timeEff<=1 && feeEff<=1 && deadEff<=1){
	    		map.put("hasAdvantage", "1");
	    	}else{
	    		if((timeEff<=1 && feeEff<=1 && deadEff>1) || (timeEff<=1 && feeEff>1 && deadEff<=1) || (timeEff>1 && feeEff<=1 && deadEff<=1)){
		    		map.put("hasAdvantage", "2");
		    	}else{
		    		map.put("hasAdvantage", "3");
		    	}
	    	}
	    }
	    resultList.addAll(list1);
	    Collections.sort(resultList, new MapComparatorImpl("asWeight", "desc"));
		return InvokeResult.success(resultList);
	}

	@Override
	public InvokeResult getDepsDRGs(IndexCalDTO dto) {
		dto.setDateFrom(DrgsIndex.formateDateFrom(dto.getDateFrom()));
		dto.setDateTo(DrgsIndex.formateDateTo(dto.getDateTo()));
		dto.setStdId(drgsIndexCalFacade.getStdID(dto.getDateFrom(), dto.getDateTo()));
		dto.setVerRegion(drgsIndexCalFacade.getGroupScheme());
		String depCode = dto.getPardepCode();
		//获取各权重区间病组集合汇总--保持优势
		List<Map<String, Object>> list1 = allWeightInterDRGs(weightInterlist, dto, "1");
		//获取各权重区间病组集合汇总--弥补不足
		List<Map<String, Object>> list2 = allWeightInterDRGs(weightInterlist, dto, "2");
		
		dto.setPardepCode(depCode);
		List<Map<String, Object>> drgsList = (List<Map<String, Object>>) getDRGsQuotas(dto, null).getData();
		List<Map<String, Object>> list11 = new LinkedList<>();
		List<Map<String, Object>> list12 = new LinkedList<>();
		List<Map<String, Object>> list13 = new LinkedList<>();
		for(Map<String, Object> m: drgsList){
			if("1".equals(m.get("hasAdvantage"))){
				list11.add(m);
			}else if("2".equals(m.get("hasAdvantage"))){
				list12.add(m);
			}else{
				list13.add(m);
			}
		}
		//list11和list1共有的DRGs
		List<Map<String, Object>> list22 = new LinkedList<>();
		for(Map<String, Object> m: list1){
			for(Map<String, Object> m1: list11){
				if(m.get("ccode").equals(m1.get("ccode"))){
					list22.add(m);
				}
			}
		}
		
		//list1去除出list22中的
		list1.removeAll(list22);
		list12.addAll(list1);
		
		//list2和list13的交集
		List<Map<String, Object>> list33 = new LinkedList<>();
		for(Map<String, Object> map: list13){
			for(Map<String, Object> m: list2){
				if(map.get("ccode").equals(m.get("ccode"))){
					list33.add(map);
				}
			}
		}
		
		Map<String, Object> resultMap = new HashMap<>();
		resultMap.put("table1", list11);
		resultMap.put("table2", list12);
		resultMap.put("table3", list33);
		
		return InvokeResult.success(resultMap);
	}
	
	//各权重区间病组集合汇总--保持优势、弥补不足、引导发展
//	@Cacheable(value = "drgscom3.1.1", key = "'allWeightInterDRGs' + #p0.dateFrom + #p0.dateTo + #p0.specCode + #p1")
	private List<Map<String, Object>> allWeightInterDRGs(List<Map<String, Object>> list, IndexCalDTO dto, String type){
		dto.setDateFrom(DrgsIndex.formateDateFrom(dto.getDateFrom()));
		dto.setDateTo(DrgsIndex.formateDateTo(dto.getDateTo()));
		dto.setStdId(drgsIndexCalFacade.getStdID(dto.getDateFrom(), dto.getDateTo()));
		dto.setVerRegion(drgsIndexCalFacade.getGroupScheme());
//		dto.setPardepCode(null);
		List<List<Map<String, Object>>> resultList = new LinkedList<>();
		for(Map<String, Object> map: list){
			String weightInter = map.get("ddesc").toString();
			InvokeResult invor = getDRGsQuotas(dto, weightInter);
			List<Map<String, Object>> ls = (List<Map<String, Object>>) invor.getData();
			List<Map<String, Object>> list1 = new LinkedList<>();
			for(Map<String, Object> m: ls){
				if(type.equals(m.get("hasAdvantage"))){
					list1.add(m);
				}
			}
			resultList.add(list1);
		}
		
		//合集
		if(resultList.size()>0){
			if(resultList.size()>1){
				List<Map<String, Object>> list1 = resultList.get(0);
				for(int i=1; i<resultList.size(); i++){
					List<Map<String, Object>> list2 = resultList.get(i);
					list1.removeAll(list2);
					list1.addAll(list2);
				}
				return list1;
			}else{
				List<Map<String, Object>> list1 = resultList.get(0);
				return list1;
			}
		}
		return new LinkedList<>();
	}
	
	@Override
	public InvokeResult getNotInDRGs(IndexCalDTO dto) {
		dto.setDateFrom(DrgsIndex.formateDateFrom(dto.getDateFrom()));
		dto.setDateTo(DrgsIndex.formateDateTo(dto.getDateTo()));
		dto.setStdId(drgsIndexCalFacade.getStdID(dto.getDateFrom(), dto.getDateTo()));
		dto.setVerRegion(drgsIndexCalFacade.getGroupScheme());
		List<Object[]> list = specialMonitorApplication.getNotInDRGs(IndexCalAssembler.toEntity(dto));
		List<Map<String, Object>> resultList = new LinkedList<>();
		for(Object[] objs: list){
			Map<String, Object> map = new HashMap<>();
			map.put("drgsCode", objs[0]);
			map.put("drgsDesc", objs[1]);
			map.put("adrgCode", objs[2]);
			map.put("adrgDesc", objs[3]);
			map.put("mdcCode", objs[4]);
			map.put("mdcDesc", objs[5]);
			map.put("asWeight", objs[6]);
			map.put("asAvgDays", objs[7]);
			map.put("asAvgFee", objs[8]);
			map.put("asRiskLevel", objs[9]);
			resultList.add(map);
		}
		return InvokeResult.success(resultList);
	}
	
	@Override
	public InvokeResult getSpecialTrendData(IndexCalDTO dto){
		dto.setDateFrom(DrgsIndex.formateDateFrom(dto.getDateFrom()));
		dto.setDateTo(DrgsIndex.formateDateTo(dto.getDateTo()));
		dto.setStdId(drgsIndexCalFacade.getStdID(dto.getDateFrom(), dto.getDateTo()));
		dto.setVerRegion(drgsIndexCalFacade.getGroupScheme());
		List<Map<String, Object>> resultList = new LinkedList<>();
		//获取基准值
		List<Map<String, Object>> listCMIs = get7QuotasJiZZ(dto);
		Map<String, Object> jzzMap = new HashMap<>();
		if(listCMIs.size()>0){
			jzzMap = listCMIs.get(0);
		}
		resultList.add(jzzMap);
		Calendar cal = Calendar.getInstance();//获取当前年份
		int year = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH) + 1;
		java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("yyyy-MM-dd");
		String today = formatter.format(new Date());
		
		if("2".equals(dto.getType3())){
			for(int i=2; i>0; i--){
				int y = year - i;
				String dateFrom = y+"-01-01";
				String dateTo = y+"-06-30";
				dto.setDateFrom(dateFrom);
				dto.setDateTo(dateTo);
				dto.setType1(y+"年"+"-上半年");
				resultList.add(getQuotas(dto));
				
				dateFrom = y+"-07-01";
				dateTo = y+"-12-31";
				dto.setDateFrom(dateFrom);
				dto.setDateTo(dateTo);
				dto.setType1(y+"年"+"-下半年");
				resultList.add(getQuotas(dto));
			}
			if(month>=7){
				int y = year;
				String dateFrom = y+"-01-01";
				String dateTo = y+"-06-30";
				dto.setDateFrom(dateFrom);
				dto.setDateTo(dateTo);
				dto.setType1(y+"年"+"-上半年");
				resultList.add(getQuotas(dto));
			}
		} else if("1".equals(dto.getType3())) {
			for(int i=5; i>0; i--){
				int y = year - i;
				String dateFrom = y+"-01-01";
				String dateTo = y+"-12-31";
				dto.setDateFrom(dateFrom);
				dto.setDateTo(dateTo);
				dto.setType1(y+"年");
				resultList.add(getQuotas(dto));
			}
		}
		
		//今年累计
		String dateFrom = year+"-01-01";
		String dateTo = today;
		dto.setDateFrom(dateFrom);
		dto.setDateTo(dateTo);
		dto.setType1(year+"年"+"-累计");
		resultList.add(getQuotas(dto));
		
		return InvokeResult.success(resultList);
	}
	
	private Map<String, Object> getQuotas(IndexCalDTO dto){
		dto.setDateFrom(DrgsIndex.formateDateFrom(dto.getDateFrom()));
		dto.setDateTo(DrgsIndex.formateDateTo(dto.getDateTo()));
		dto.setStdId(drgsIndexCalFacade.getStdID(dto.getDateFrom(), dto.getDateTo()));
		dto.setVerRegion(drgsIndexCalFacade.getGroupScheme());
		
		List<Map<String, Object>> listCMI = get7Quotas(dto);
		//计算产能得分
		dto.setQuotaCode("spCapScore");
		List<Map<String, Object>> listCap = monitor(dto);
		//计算效率得分
		dto.setQuotaCode("spEffScore");
		List<Map<String, Object>> listEff = monitor(dto);
		//计算安全得分
		dto.setQuotaCode("spQuaScore");
		List<Map<String, Object>> listQua = monitor(dto);
		listCMI = mapList(listCMI, listCap, "");
		listCMI = mapList(listCMI, listEff, "");
		listCMI = mapList(listCMI, listQua, "");
		//计算安全得分基准值
		dto.setQuotaCode("spQuaScores");
		List<Map<String, Object>> listQuas = monitor(dto);
		listCap = mapList(listCap, listQuas, "");
		double spCapScores = 1*0.204+0.75*0.181;
		double spEffScores = 0.192+0.128;
		Map<String, Object> map = new HashMap<>();
		if(listCMI.size()>0){
			map = listCMI.get(0);
			map.put("year", dto.getType1());
			double spCapScore = map.get("spCapScore")!=null?Double.parseDouble(map.get("spCapScore").toString()):0;
			double spEffScore = map.get("spEffScore")!=null?Double.parseDouble(map.get("spEffScore").toString()):0;
			double spQuaScore = map.get("spQuaScore")!=null?Double.parseDouble(map.get("spQuaScore").toString()):0;
			double spQuaScores = map.get("spQuaScores")!=null?Double.parseDouble(map.get("spQuaScores").toString()):0;
			if(spCapScore<spCapScores){
				map.put("spType", "一");
			}else if(spEffScore<spEffScores){
				map.put("spType", "二");
			}else if(spQuaScore<spQuaScores){
				map.put("spType", "三");
			}else{
				map.put("spType", "四");
			}
		}
		return map;
	}
	
	@Override
	public InvokeResult getTimeFeeLowDRGs(IndexCalDTO dto){
		dto.setDateFrom(DrgsIndex.formateDateFrom(dto.getDateFrom()));
		dto.setDateTo(DrgsIndex.formateDateTo(dto.getDateTo()));
		dto.setStdId(drgsIndexCalFacade.getStdID(dto.getDateFrom(), dto.getDateTo()));
		dto.setVerRegion(drgsIndexCalFacade.getGroupScheme());
		List<Map<String, Object>> list = specialMonitorApplication.getDRGsByDepsOrWeight(IndexCalAssembler.toEntity(dto), null, null);
		List<Map<String, Object>> resultList = new LinkedList<>();
		for(Map<String, Object> map: list){
			Double timeEff = map.get("timeEff")!=null?Double.parseDouble(map.get("timeEff").toString()):null;
			Double feeEff = map.get("feeEff")!=null?Double.parseDouble(map.get("feeEff").toString()):null;
			if(timeEff!=null && feeEff!=null && timeEff>1 && feeEff>1){
				resultList.add(map);
			}
		}
		return InvokeResult.success(resultList);
	}

	@Override
	public InvokeResult loadCaseDistributeData(IndexCalDTO dto, String[] intervalParam) {
		// 查询sql 和查询条件
		List<Map<String,Object>> queryList  = new ArrayList<>() ;
		StringBuilder sql = new StringBuilder();
		sql.append(" select clispec.spec_code ccode ,clispec.spec_desc ddesc, count(distinct b.pardrg_code) drgscnt, count(ipinfo.pmainindex) casecnt    \n ");
		sql.append(" from drgs.mr_baseinfo a \n ");
		sql.append(" left join drgs.mr_ipinfo ipinfo on a.pmainindex = ipinfo.pmainindex \n ");
		sql.append(" left join drgs.t_patientdrg b   \n ");
		sql.append(" on ipinfo.pmainindex=b.parid and b.ver_region = :verRegion \n ");
		sql.append(" left join drgs.t_clispecdrgs cd \n ");
		sql.append(" on cd.csd_drg_code = b.pardrg_code and cd.csd_ver_code = b.ver_code \n ");
		sql.append(" left join drgs.t_clispec clispec on clispec.spec_code = cd.csd_spec_code \n ");
		sql.append(" left join drgs.t_annualstd e   \n ");
		sql.append(" on b.pardrg_code=e.as_drg_code and e.AS_ID = :stdId \n ");
		sql.append(" where to_char(ipinfo.P00290000,'yyyy-mm-dd') between  :dateFrom  and  :dateTo \n ");
		sql.append(" and e.as_weight is not null  \n ");
		sql.append(" and ipinfo.P00300001 is not null \n ");
		sql.append(" and b.pardrg_code is not null  \n ");
		sql.append(" and clispec.spec_code is not null \n ");
		sql.append(" and e.as_weight > :weightMin \n ");
		sql.append(" and e.as_weight <= :weightMax \n "); 
		//***医院编码***
		if(StringUtils.hasLength(dto.getHospCode())){
			sql.append(" and instr(:hospCode,a.p00010001)>0 \n ");
		}
		sql.append(" and e.as_weight <= :weightMax \n "); 
		
		sql.append(" group by clispec.spec_code ,clispec.spec_desc \n ");
		sql.append(" order by clispec.spec_code \n ");
		dto.setDateFrom(DrgsIndex.formateDateFrom(dto.getDateFrom()));
		dto.setDateTo(DrgsIndex.formateDateTo(dto.getDateTo()));
	    String verRegion = drgsIndexCalFacade.getGroupScheme();
	    dto.setVerRegion(verRegion);
	    String stdId = drgsIndexCalFacade.getStdID(dto.getDateFrom(), dto.getDateTo());
		dto.setStdId(stdId);
		for(int i=0 ; i<intervalParam.length-1 ; i++) {
			Map<String,Object> queryMap = new HashMap<>() ;
			Map<String,Object> condition = new HashMap<String,Object>() ;
			condition.put("dateFrom", dto.getDateFrom());
			condition.put("dateTo", dto.getDateTo());
			condition.put("verRegion", verRegion);
			condition.put("stdId", stdId);
			condition.put("weightMin", intervalParam[i]);
			condition.put("weightMax", intervalParam[i+1]);
			queryMap.put("queryId",i) ;
			queryMap.put("sql", sql.toString()) ;
			queryMap.put("condition", condition) ;
			queryList.add(queryMap) ;
		}
		List<Map<String, Object>> resultList= specialMonitorApplication.multithreadQuery(queryList) ;
		return InvokeResult.success(resultList);
	}

	@Override
	public InvokeResult saveIntervalParam(SizerConditionDTO sc) {
		SizerCondition  sizerCondition =  SizerConditionAssembler.toEntity(sc) ;
		sizerConditionApplication.creatSizerCondition(sizerCondition);
		return InvokeResult.success() ;
	}

	@Override
	public InvokeResult findConditionByMoudkeCode(String moudkeCode) {
		SizerCondition condtion = sizerConditionApplication.findSizerCondition(moudkeCode);
		return InvokeResult.success(condtion);
	}

	@Override
	public Map<String,Object> loadDrgsDistributeData(IndexCalDTO dto, String[] intervalParam) {
	    // 获取标杆定位id 
	    String stdId = drgsIndexCalFacade.getStdID(dto.getDateFrom(), dto.getDateTo());
	    AnnualSTD annualSTD = new AnnualSTD();
	    annualSTD.setAsId(stdId);
	    List<AnnualSTD> annualSTDList = annualSTDApplication.findAllAnnualSTD(annualSTD ) ;
	    Map<String,Object> resultMap = new HashMap<>() ;
		for(int i=0 ; i<intervalParam.length-1 ; i++) {
			List<AnnualSTD> resultlList = filterListByWeight(annualSTDList,MonitorResultUtil.objectToDouble(intervalParam[i]),MonitorResultUtil.objectToDouble(intervalParam[i+1])) ;
			resultMap.put(i+"", resultlList.size()) ;
		}
		resultMap.put("total", annualSTDList.size()) ;
		return resultMap ;
	}
	
	/**
	 *  过滤权重区间病组
	 *  filterListByWeight.  
	 *  @Description：
	 *  @Author ChenHanlin
	 *  @param astdList
	 *  @param weightMin
	 *  @param weightMax
	 *  @return 
	 *  @Date:2018年3月27日上午11:06:24
	 */
	private List<AnnualSTD> filterListByWeight(List<AnnualSTD> astdList,Double weightMin,Double weightMax){
		List<AnnualSTD> listT = new ArrayList<>() ;
		for(AnnualSTD annualSTD : astdList) {
			if(annualSTD.getAsWeight()>weightMin && annualSTD.getAsWeight()<=weightMax) {
				listT.add(annualSTD) ;
			}
		}
		return listT;
	}
	
	@Override
	public InvokeResult findWeightsExtremum(IndexCalDTO dto) {
		Double maxVal = null ;
		Double minVal = null ;
		Map<String,Object> resultMap = annualSTDApplication.findWeightsExtremum(drgsIndexCalFacade.getStdID(dto.getDateFrom(), dto.getDateTo())) ;
		String maxs = resultMap.get("WEIGHTMAX") == null ? null : resultMap.get("WEIGHTMAX").toString() ;
		String mins = resultMap.get("WEIGHTMIN") == null ? null : resultMap.get("WEIGHTMIN").toString() ;
		Map<String,Object> extremum = new HashMap<>() ;
		// 转换时发生异常则返回null
		try {
			maxVal = Double.parseDouble(maxs) ;
			minVal = Double.parseDouble(mins) ;
		} catch (Exception e) {
			e.printStackTrace();
		}
		extremum.put("max", maxVal) ;
		extremum.put("min", minVal) ;
		return InvokeResult.success(extremum);
	}
	
}
